/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_httpd.htm
 *
 * Zhiqim Httpd is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.httpd.context.service;

import java.io.IOException;

import org.zhiqim.httpd.HttpExecutor;
import org.zhiqim.httpd.HttpRequest;
import org.zhiqim.httpd.HttpResponse;
import org.zhiqim.httpd.context.ZmlContextConstants;
import org.zhiqim.httpd.context.core.Context;
import org.zhiqim.kernel.util.Strings;
import org.zhiqim.kernel.util.Validates;

/**
 * Ajax服务，提供给页面调用，验证方式如下：
 * 1.连接提供当页面地址且在ZAction中能找到，格式如：/service/ajax?path=window.location.pathname
 * 2.必须有会话，且会话不是首次创建。
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 * @version v1.3.0 @author zouzhigang 2017-3-15 增加对表单方式的提交
 */
public class AjaxService implements HttpExecutor, ZmlContextConstants
{
    @Override
    public boolean isMatch(String pathInContext)
    {
        return _PATH_SERVICE_AJAX_.equals(pathInContext);
    }
    
    @Override
    public void handle(HttpRequest request, HttpResponse response) throws IOException
    {
        String mimeType = request.getMimeType();
        if (!request.isXMLHttpRequest() || !_POST_.equals(request.getMethod()) || !_UTF_8_.equalsIgnoreCase(request.getCharacterEncodingHeader()) ||
            !(_TEXT_PLAIN_.equals(mimeType) || _APPLICATION_X_WWW_FORM_.equals(mimeType) || _APPLICATION_XML_.equals(mimeType) || _APPLICATION_JSON_.equals(mimeType)))
        {//不是AJAX/POST/UTF-8和的访问禁止，不是TEXT/FORM/XML/JSON类型的不支持
            response.sendError(_403_FORBIDDEN_);
            return;
        }
        
        String path = request.getParameterOnURL(ZC_PATH);
        String serviceId = Strings.trim(request.getHeader(_X_RMI_SERVICE_), _EMPTY_);
        String clazz = Strings.trim(request.getHeader(_X_RMI_CLASS_), _EMPTY_);
        String method = request.getHeader(_X_RMI_METHOD_);
        if (Validates.isEmptyBlank(path) || (Validates.isEmptyBlank(clazz) && Validates.isEmptyBlank(serviceId)) || Validates.isEmptyBlank(method))
        {//必须指定访问路径，类和方法名，否则认为是非法请求
            response.sendError(_412_PRECONDITION_FAILED_);
            return;
        }
        
        RmiService service = ((Context)request.getContext()).getServiceExecutor().getRmiService();
        
        String classNameId = Validates.isEmpty(clazz)?serviceId:clazz;
        String interceptors = request.getContextAttributeString(_SERV_AJAX_INTERCEPTOR_);
        if (!service.chkInterceptor(request, response, interceptors, classNameId, method, null))
        {//如果有配置缺省拦截器时，有错误或认证失败不再继续
            return;
        }
        
        //最后由RMI服务处理
        service.service(request, response);
    }
}
